#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
文件名称: student_archive_log.py
完整存储路径: backend/models/student_archive_log.py
功能说明: 学生档案操作日志数据模型
使用说明: 记录学生档案的创建、更新、删除等操作日志
"""

from datetime import datetime, timedelta
import json
import enum
from sqlalchemy import Column, Integer, String, Text, DateTime, Enum
from backend.infrastructure.database import db

def get_beijing_time():
    """返回东八区当前时间"""
    return datetime.utcnow() + timedelta(hours=8)

class StudentLogAction(enum.Enum):
    """学生档案日志操作类型枚举"""
    CREATE = "CREATE"       # 创建学生档案
    UPDATE = "UPDATE"       # 更新学生档案
    DELETE = "DELETE"       # 删除学生档案
    RESTORE = "RESTORE"     # 恢复学生档案
    MERGE = "MERGE"         # 合并学生档案
    TRANSFER = "TRANSFER"   # 转学转班
    GRADUATE = "GRADUATE"   # 毕业处理

class StudentArchiveLog(db.Model):
    """学生档案操作日志表"""
    __tablename__ = 'student_archive_logs'
    
    id = Column(Integer, primary_key=True, autoincrement=True)
    student_id = Column(Integer, nullable=False, comment='学生ID')
    action = Column(Enum(StudentLogAction), nullable=False, comment='操作类型')
    operator = Column(String(100), nullable=False, comment='操作人')
    operation_time = Column(DateTime, default=datetime.now, comment='操作时间')
    old_content = Column(Text, comment='修改前的数据(JSON格式)')
    new_content = Column(Text, comment='修改后的数据(JSON格式)')
    operation_desc = Column(String(500), comment='操作描述')
    ip_address = Column(String(50), comment='操作IP地址')
    user_agent = Column(String(500), comment='用户代理')
    module_source = Column(String(50), comment='操作来源模块')
    created_at = Column(DateTime, default=datetime.now, comment='日志创建时间')
    
    def to_dict(self):
        """转换为字典格式"""
        # 处理时区
        created_at = self.created_at + timedelta(hours=8) if self.created_at and self.created_at.tzinfo is None else self.created_at
        operation_time = self.operation_time + timedelta(hours=8) if self.operation_time and self.operation_time.tzinfo is None else self.operation_time
        
        return {
            "id": self.id,
            "student_id": self.student_id,
            "action": self.action.value if self.action else None,
            "operator": self.operator,
            "operation_time": operation_time.isoformat() if operation_time else "",
            "old_content": self.old_content,
            "new_content": self.new_content,
            "operation_desc": self.operation_desc,
            "ip_address": self.ip_address,
            "user_agent": self.user_agent,
            "module_source": self.module_source,
            "created_at": created_at.isoformat() if created_at else ""
        }
    
    # === 统一日志服务标准方法 ===
    @classmethod
    def log_create(cls, student, extension_data=None, operator='系统', ip_address=None, user_agent=None):
        """记录学生档案创建操作日志"""
        try:
            # 构建完整的学生档案数据
            student_data = student.to_dict() if hasattr(student, 'to_dict') else {}
            if extension_data:
                student_data['extension_info'] = extension_data
            
            log = cls(
                student_id=student.id if hasattr(student, 'id') else student.get('id'),
                action=StudentLogAction.CREATE,
                operator=operator,
                operation_time=datetime.now(),
                old_content='{}',  # 创建时无旧内容
                new_content=json.dumps(student_data, ensure_ascii=False, default=str),
                operation_desc=f'创建学生档案 - 姓名: {student.name if hasattr(student, "name") else student.get("name", "未知")}, 教育ID: {student.education_id if hasattr(student, "education_id") else student.get("education_id", "未知")}',
                ip_address=ip_address,
                user_agent=user_agent,
                module_source='student_archive'
            )
            
            db.session.add(log)
            db.session.commit()
            return True
            
        except Exception as e:
            db.session.rollback()
            import logging
            logging.error(f"记录学生档案创建日志失败: {e}")
            return False
    
    @classmethod  
    def log_update(cls, student_id, old_data, new_data, updated_fields, operator='系统', ip_address=None, user_agent=None):
        """记录学生档案更新操作日志"""
        try:
            # 构建操作描述
            basic_fields = updated_fields.get('basic', [])
            extension_fields = updated_fields.get('extension', [])
            
            desc_parts = []
            if basic_fields:
                desc_parts.append(f"基本信息字段: {', '.join(basic_fields)}")
            if extension_fields:
                desc_parts.append(f"扩展信息字段: {', '.join(extension_fields)}")
            
            operation_desc = f"更新学生档案 - {'; '.join(desc_parts)}"
            
            log = cls(
                student_id=student_id,
                action=StudentLogAction.UPDATE,
                operator=operator,
                operation_time=datetime.now(),
                old_content=json.dumps(old_data, ensure_ascii=False, default=str),
                new_content=json.dumps(new_data, ensure_ascii=False, default=str),
                operation_desc=operation_desc,
                ip_address=ip_address,
                user_agent=user_agent,
                module_source='student_archive'
            )
            
            db.session.add(log)
            db.session.commit()
            return True
            
        except Exception as e:
            db.session.rollback()
            import logging
            logging.error(f"记录学生档案更新日志失败: {e}")
            return False
    
    @classmethod
    def log_delete(cls, student_id, student_data, operator='系统', ip_address=None, user_agent=None):
        """记录学生档案删除操作日志"""
        try:
            log = cls(
                student_id=student_id,
                action=StudentLogAction.DELETE,
                operator=operator,
                operation_time=datetime.now(),
                old_content=json.dumps(student_data, ensure_ascii=False, default=str),
                new_content='{}',  # 删除后无新内容
                operation_desc=f'删除学生档案 - 姓名: {student_data.get("name", "未知")}, 教育ID: {student_data.get("education_id", "未知")}',
                ip_address=ip_address,
                user_agent=user_agent,
                module_source='student_archive'
            )
            
            db.session.add(log)
            db.session.commit()
            return True
            
        except Exception as e:
            db.session.rollback()
            import logging
            logging.error(f"记录学生档案删除日志失败: {e}")
            return False
    
    @classmethod
    def log_restore(cls, student_id, operator='系统', operation_desc='恢复学生档案', 
                   restored_from_log_id=None, old_content=None, new_content=None,
                   ip_address=None, user_agent=None):
        """
        记录学生档案恢复操作日志
        
        Args:
            student_id: 学生ID
            operator: 操作人
            operation_desc: 操作描述
            restored_from_log_id: 来源日志ID
            old_content: 恢复前的数据
            new_content: 恢复后的数据
            ip_address: 操作IP
            user_agent: 用户代理
        """
        try:
            # 构建完整的操作描述
            full_desc = operation_desc
            if restored_from_log_id:
                full_desc += f" (来源日志ID: {restored_from_log_id})"
            
            log = cls(
                student_id=student_id,
                action=StudentLogAction.RESTORE,
                operator=operator,
                operation_time=get_beijing_time(),
                old_content=old_content,
                new_content=new_content,
                operation_desc=full_desc,
                ip_address=ip_address,
                user_agent=user_agent,
                module_source='student_archive'
            )
            
            db.session.add(log)
            db.session.commit()
            
            return {'success': True, 'log_id': log.id}
            
        except Exception as e:
            db.session.rollback()
            import logging
            logging.error(f"记录学生档案恢复日志失败: {e}")
            return {'success': False, 'error': str(e)}
    
    @classmethod
    def get_student_logs(cls, student_id, limit=50, action=None):
        """获取指定学生的操作日志"""
        try:
            query = cls.query.filter_by(student_id=student_id)
            
            if action:
                query = query.filter_by(action=action)
            
            logs = query.order_by(cls.operation_time.desc()).limit(limit).all()
            
            return {
                'success': True,
                'student_id': student_id,
                'total': len(logs),
                'logs': [log.to_dict() for log in logs]
            }
            
        except Exception as e:
            import logging
            logging.error(f"获取学生档案日志失败: {e}")
            return {
                'success': False,
                'error': str(e),
                'logs': []
            }
    
    @classmethod
    def get_all_logs(cls, limit=100, action=None, operator=None, start_date=None, end_date=None):
        """获取所有学生档案操作日志（带筛选条件）"""
        try:
            query = cls.query
            
            if action:
                query = query.filter_by(action=action)
            
            if operator:
                query = query.filter(cls.operator.like(f'%{operator}%'))
            
            if start_date:
                query = query.filter(cls.operation_time >= start_date)
            
            if end_date:
                query = query.filter(cls.operation_time <= end_date)
            
            logs = query.order_by(cls.operation_time.desc()).limit(limit).all()
            
            return {
                'success': True,
                'total': len(logs),
                'logs': [log.to_dict() for log in logs]
            }
            
        except Exception as e:
            import logging
            logging.error(f"获取所有学生档案日志失败: {e}")
            return {
                'success': False,
                'error': str(e),
                'logs': []
            }
